package thread;


import jdk.management.resource.internal.inst.ThreadRMHooks;

@SuppressWarnings({"all"})
class MyBlockingQueue {
    // 保存数据的本体
    private int[] data = new int[1000];
    // 有效元素的个数
    private int size = 0;
    // 队首下标
    private int head = 0;
    // 队尾下标
    private int tail = 0;

    // 专门的锁对象
    private Object locker = new Object();


    // 入队列
    public void put(int value) throws InterruptedException {
        synchronized (locker) {
            if (size == data.length) {
                // 队列满了，暂时直接返回
                // return;
                locker.wait();
            }
            // 把新的元素放到 tail 位置上
            data[tail] = value;
            tail++;
            // 处理 tail 到达数组末尾的情况
            if (tail >= data.length) {
                tail = 0;
            }
            // 可读性差
            // tail = tail % data.length;
            size++; // 插入完成之后要修改元素个数
            // 如果入队列成功，则队列非空，于是就唤醒 take 中的阻塞等待
            locker.notify();
        }
    }


    // 出队列
    public Integer take() throws InterruptedException {
        synchronized (locker) {
            if (size == 0) {
                // 如果队列为空，返回一个非法值
                // return null;
                locker.wait();
            }
            // 取出 head 位置的元素
            int ret = data[head];
            head++;
            if (head >= data.length) {
                head = 0;
            }
            size--;
            // take 成功之后， 就唤醒 put 中的等待
            locker.notify();
            return ret;
        }
    }
}

@SuppressWarnings({"all"})
public class Demo4 {
    private static MyBlockingQueue queue = new MyBlockingQueue();

    public static void main(String[] args) {
        // 实现一个简单的生产者消费者模型
        Thread producer = new Thread(() -> {
            int num = 0;
            while (true) {
                try {
                    System.out.println("生产了：" + num);
                    queue.put(num);
                    num++;
                    //Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        producer.start();

        Thread customer = new Thread(() -> {
           while (true) {
               try {
                   int num = queue.take();
                   System.out.println("消费了："+ num);
                   Thread.sleep(500);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
           }
        });
        customer.start();

//        MyBlockingQueue queue = new MyBlockingQueue();
//        queue.put(1);
//        queue.put(2);
//        queue.put(3);
//        queue.put(4);
//        int ret =0 ;
//        ret = queue.take();
//        System.out.println(ret);
//        ret = queue.take();
//        System.out.println(ret);
//        ret = queue.take();
//        System.out.println(ret);
//        ret = queue.take();
//        System.out.println(ret);

    }
}
